package com.awenhui.demo.controller;

/**
 * @author yuxf on 2020/4/9 13:07
 * @version 1.0
 */

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

import com.awenhui.demo.core.base.ActionResult;
import com.awenhui.demo.core.base.BaseController;
import com.awenhui.demo.core.utils.*;
import com.awenhui.demo.core.utils.poi.ExcelUtils;
import com.awenhui.demo.dao.*;
import com.awenhui.demo.feign.TestFiegnClient;
import com.awenhui.demo.feign.dto.GyfcResult;
import com.awenhui.demo.feign.dto.SalesOfNewHouseDto;
import com.awenhui.demo.model.*;
import com.awenhui.demo.model.em.Color;
import com.awenhui.demo.model.entity.*;
import com.awenhui.demo.log.LogOperation;
import com.awenhui.demo.config.Person;
import com.awenhui.demo.model.po.TestPo;
import com.awenhui.demo.service.RoleServiceImpl;

import com.awenhui.demo.service.DemoService;

//import com.github.pagehelper.PageHelper;
//import com.github.pagehelper.PageInfo;
import com.awenhui.demo.service.SysUserService;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.zxing.WriterException;
//import com.icbc.api.DefaultIcbcClient;
//import com.icbc.api.IcbcApiException;
//import com.icbc.api.IcbcConstants;
//import com.icbc.api.UiIcbcClient;
//import com.icbc.api.request.CardbusinessAggregatepayB2cOnlineOrderqryRequestV1;
//import com.icbc.api.request.CardbusinessEpaypcConsumptionRequestV1;
//import com.icbc.api.request.CardbusinessQrcodeQrgenerateRequestV1;
//import com.icbc.api.response.CardbusinessAggregatepayB2cOnlineOrderqryResponseV1;
//import com.icbc.api.response.CardbusinessQrcodeQrgenerateResponseV1;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringValueResolver;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Api(value = "演示Value")
@RestController
@RequestMapping("/demo")
@Slf4j
public class DemoController extends BaseController implements BeanNameAware, EmbeddedValueResolverAware {

    Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    MetaDataMapper metaDataMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    TestMapper testMapper;

    @Autowired
    SuperMapper superMapper;

    @Autowired
    UserAnnotationMapper userAnnotationMapper;
    @Autowired
    ApplicationContext applicationContext;
    @Autowired
    SysUserService sysUserService;

    @Autowired
    SqlSessionFactory sqlSessionFactory;

    @Autowired
    Executor myTaskExecutor;

    @Autowired
    TestFiegnClient testFiegnClient;

    @Value("${test.enc}")
    String enc;


    @Override
    public void setBeanName(String name) {


        System.out.println("BEANNAME:" + name);

        LocalDateTime.now().plusSeconds(60);
        LocalDateTime.now().plusMinutes(60);
        LocalDateTime.now().plusHours(60);
    }


    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.resolver = resolver;
        System.out.println("值解析器：" + resolver.resolveStringValue("${os.name}"));
    }


    public final RoleServiceImpl roleService;
    public Person person;
    //值解析器
    public StringValueResolver resolver;

    @Autowired
    public DemoService demoService;


    public DemoController( RoleServiceImpl roleService, Person person) {

        this.roleService = roleService;
        this.person = person;
    }


    @Value("${env:unknown}")
    private String env;
    @Value("${name}")
    private String name;
    @Value("${os.name}")
    private String osName;

    @GetMapping("/testSql")
    public Object testSql()
    {
        Configuration configuration = sqlSessionFactory.getConfiguration();
        if(configuration!=null){
            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();

            return "获取成功";
        }else{
            return "获取失败";
        }


    }


    @GetMapping("/testFeign")
    public Object testFeign()
    {
        GyfcResult<SalesOfNewHouseDto> salesOfNewHouse = testFiegnClient.getSalesOfNewHouse("全部", "全部", "全部", "2021-01-01", "2021-06-30");

        return salesOfNewHouse;
    }

    /**
     * 测试spring的线程池
     * @return
     */
    @GetMapping("/testPool")
    public Object testPool()
    {
        myTaskExecutor.execute(()->{
            System.out.println("ThreadPoolTaskExecutor execute()");
        });
        return "成功";
    }


    @GetMapping("/testSelect/{uid}")
    public Object testSelect(@PathVariable("uid") Long uid) throws JsonProcessingException {
        UaUserEntity uaUserEntity = new UaUserEntity();
        uaUserEntity.setUserId(uid);

        UaUserEntity user1 = superMapper.select(uaUserEntity, UaUserEntity.class);


        HashMap<String, Object> result = new HashMap<>();
        result.put("select", user1);


        return result;
    }
    @Autowired
    RabbitTemplate rabbitTemplate;  //使用RabbitTemplate,这提供了接收/发送等等方

    @GetMapping("/mqTest")
    public Object mqTest() throws JsonProcessingException {



        String messageId = String.valueOf(UUID.randomUUID());
        String messageData = "test message, hello!";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map=new HashMap<>();
        map.put("messageId",messageId);
        map.put("messageData",messageData);
        map.put("createTime",createTime);
        //将消息携带绑定键值：TestDirectRouting 发送到交换机TestDirectExchange
        long start=System.currentTimeMillis();
        rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
        log.info("插入队列用时：{}",System.currentTimeMillis()-start);
        start=System.currentTimeMillis();

        userMapper.configGetUsers2();
        log.info("连接数据库用时：{}",System.currentTimeMillis()-start);
        return "ok";

    }

    @GetMapping("/testEnumBind/{enumValue}")
    public Object testEnumBind(@PathVariable("enumValue") Color color)
    {

       return color;
    }

    @GetMapping("/testGetOne/{userName}")
    public Object testGetOne(@PathVariable("userName") String userName)
    {
        SysUserEntity sysUserEntity = sysUserService.testGetOne(userName);
        return sysUserEntity;
    }

    @GetMapping("/testGetUser/{uid}")
    public Object testGetUser(@PathVariable("uid") Long uid) throws JsonProcessingException {

        UaUserEntity user = userAnnotationMapper.getUserById(uid);

        HashMap<String, Object> result = new HashMap<>();
        result.put("select", user);
        return result;
    }

    @GetMapping("/testList")
    public Object testList() {
        List<TestPo> test = testMapper.getTest();
        return test;
    }

    @GetMapping("/testAop")
    @LogOperation(module = "Demo",action = "测试AOP",busiParamName = "person.name")
    public Object testAop(PersonDto person) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("nname", person.getName());
        map.put("aage", person.getAge());
        return map;
    }

    @GetMapping("testParam1")
    public Object testParam1(int id, ParamDto1 dto1, @RequestHeader("User-Agent") String agent, Person person) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("dto1", dto1);
        map.put("contentType", agent);
        map.put("person", person);
        return map;
    }

    /**
     * 返回当前环境
     *
     * @return
     */
    @GetMapping("evn")
    public ResponseEntity<?> env() {
        return ResponseEntity.ok(env);
    }

    /**
     * 默认页面
     *
     * @return
     */
    @GetMapping({"", "/index"})
    public ResponseEntity<?> index() {
        System.out.println("多久呢");
        List<String> list = new ArrayList<>();
        list.add("默认页面");
        list.add("于新方");
        list.add("张三");
        list.add("李四");
        list.add("配置文件name：" + name);
        list.add(System.currentTimeMillis() + "");
        list.add("ENC:" + enc);
        list.add(applicationContext.getEnvironment().getProperty("server.port"));

        return ResponseEntity.ok(list);
    }

    @GetMapping("demo01")
    public ResponseEntity<?> demo01() {

        List<String> list = new ArrayList<>();
        list.add("于新方");
        list.add("张三");
        list.add("李四");
        list.add("配置文件name：" + name);
        list.add(System.currentTimeMillis() + "");
        return ResponseEntity.ok(list);
    }

    /**
     * demo02
     *
     * @param request
     * @return
     */
    @PostMapping("demo02")
    @ApiOperation(value = "演示02")

    public ResponseEntity<?> demo02(@RequestBody Demo01Request request) {
        return ResponseEntity.ok("testPost");
    }

    @PostMapping("dtoTest")
    public Object dtoTest(@RequestBody DtoTestModel model) {
        return model;
    }

    /**
     * 手动抛出异常
     *
     * @return
     * @throws Exception
     */
    @GetMapping("exp")
    public ResponseEntity<?> exp() throws Exception {

        throw new Exception("exp出错了");
    }

    /**
     * 手动抛出异常
     *
     * @return
     * @throws Exception
     */
    @GetMapping("logAop")
    @LogOperation(module = "测试模块",action = "日志切面",excluedeArgs = {"request"})
    public Map logAop(String name, Integer age,HttpServletRequest request) throws NoSuchFieldException, NoSuchMethodException {


        Class clazz = this.getClass();

        //Field
        clazz.getField("name");
        clazz.getFields();
        clazz.getDeclaredField("name");
        clazz.getDeclaredFields();

        //Method
        clazz.getMethod("getName");
        clazz.getMethods();
        clazz.getDeclaredMethod("getName");
        clazz.getDeclaredMethods();
        //Annotation
        clazz.getAnnotation(Override.class);

        //Constructor
        clazz.getConstructor(String.class,int.class);
        clazz.getConstructors();
        clazz.getDeclaredConstructor(String.class);
        clazz.getDeclaredConstructors();

        //Superclass
        clazz.getSuperclass();

        //Interfaces
        clazz.getInterfaces();

        //name
        clazz.getName(); //获取类全名(含包名)
        clazz.getSimpleName();//获取类名（不含包名）



        Map<String, Object> map = new HashMap<>();
        map.put("name", name);
        map.put("age", age);
        map.put("code",1);
        return map;





    }

    @GetMapping("qrCode")
    public void qrCode(HttpServletResponse response) throws IOException, WriterException {
        BufferedImage bufferedImage = QrCodeUtils.qrCode("于新方 http://wedasdmkldfn是多少你答非的是否能是劳动法开始的你发斯蒂芬豆腐脑是劳动法啊啊发马拉松的防溺水发送玛琳菲森54910165edmekhfbqdahqibdqkwddwqd ", 300);
        QrCodeUtils.writeToResponse(response, bufferedImage);
    }

    /**
     * @return
     */
    @GetMapping("bl")
    public String bl() {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        for (String item : list) {
            System.out.println("姓*名：" + item);
        }

        return name;

    }

    @GetMapping("user")
    public HashMap<String, String> user(Authentication authenticationParam, @AuthenticationPrincipal UserDetails userDetails) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String name = authentication.getName();
        HashMap<String, String> map = new HashMap<>();
        map.put("name", name);
        map.put("auth", authentication.getAuthorities().toString());
        return map;
    }

    @ApiOperation(value = "添加角色")
    @PostMapping("addRole")
    public ActionResult<?> addRole() {
        RoleEntity role = roleService.addRole();
        return success(role);
    }

    @ApiOperation(value = "查询角色")
    @GetMapping("findRoleByName")
    public ActionResult<?> findRoleByName(@ApiParam(value = "角色名称", name = "name") @RequestParam String name) {
        List<RoleEntity> roles = roleService.findByName(name);

        "select *from ua_user where name ={name}".replace("{name}", "zttm").replace("{age}", "18");


        return success(roles);
    }

    @ApiOperation(value = "雪花算法")
    @GetMapping("snowFlake")
    public ActionResult<?> snowFlake() {
        for (int i = 0; i < 100; i++) {
            System.out.println(SnowFlake.nextId());
        }
        return success("sysout");
    }

    @GetMapping("testLog")
    public ActionResult<?> testLog() {
        String name = "于新方";
        String password = "123456abc";


        logger.debug("debug用户名：{}，密码：{}", name, password);
        logger.info("info用户名：{}，密码：{}", name, password);
        logger.error("error用户名：{}，密码：{}", name, password);
        return success();

    }

    /**
     * 上传文件
     *
     * @return
     */
    @PostMapping("upload")
    public ActionResult<?> upload(MultipartFile file) throws IOException {
        //文件上传路径
        File uploadFileDir = new File(
                new File(ResourceUtils.getURL("classpath:").getPath())
                        .getParentFile().getAbsolutePath(), "upload");
        if (!uploadFileDir.exists()) uploadFileDir.mkdirs();
        String fileName = file.getOriginalFilename();
        File descFile = new File(uploadFileDir + File.separator + fileName);
        file.transferTo(descFile);
        return success();
    }


    /**
     * 下载文件
     *
     * @return
     */
    @GetMapping("download")
    public ResponseEntity<byte[]> download(String fileName) throws IOException {
        ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
        File file = new File("d:\\demo\\" + fileName);
        builder.contentLength(file.length());
        // application/octet-stream 二进制数据流（最常见的文件下载）
        builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
        // 使用URLEncoding.decode对文件名进行解码
        fileName = URLEncoder.encode(fileName, "UTF-8");
        builder.header("Content-Disposition", "attachment; filename=" + fileName);
        return builder.body(Files.readAllBytes(file.toPath()));
    }


    //缩略图
    @GetMapping("thumb")
    public void thumb(HttpServletResponse response) throws IOException {
        BufferedImage image = ImageIO.read(new URL("http://note.youdao.com/yws/public/resource/db755721630f6f66b1c64bc4b02d85f3/xmlnote/298C6C03C8454ABEBAEA8837D388CD4E/3210"));


        String fname = "D:\\demo\\thumb\\" + UUID.randomUUID().toString() + ".jpg";
        Thumbnails.of(image).size(200, 200).toFile(fname);

        response.setContentType("image/jpg");
        Thumbnails.of(image).size(200, 200).outputFormat("jpg").toOutputStream(response.getOutputStream());
    }


    @GetMapping("downloadExcel")
    public void downloadExcel(HttpServletResponse response) throws Exception {
        List<PersonJb> list = new ArrayList<>();
        PersonJb yuxf = new PersonJb("于新方1", 17);
        yuxf.setBirth(new Date());
        list.add(yuxf);
        list.add(new PersonJb("何刘惠2", 18));
        PersonJb wcf = new PersonJb("王春芳3", 20);
        yuxf.setBirth(new Date());
        list.add(wcf);
        Workbook workbook = ExcelUtils.getWorkbook("d:\\demo\\1.xlsx", Arrays.asList("name", "age", "birth", "longg"), list, r -> r.getRow().setHeight((short) (40 * 20)), null);
        String fileName = UUID.randomUUID().toString().split("-")[0] + ".xls";
        ExcelUtils.outEcxelFile(workbook, response, fileName);

    }

    /**
     * 获取时间
     *
     * @return
     */
    @GetMapping("getTime")
    public ActionResult<?> getTime(String key) {
        HashMap<String, String> hash = new HashMap<>();
        hash.put("1", "123");
        hash.put("2", "123");
        hash.put("3", "123");
        hash.put("4", "123");
        String time = demoService.getTime(key);
        return success(time);
    }

    /**
     * 获取缓存列表
     *
     * @return
     */
    @GetMapping("getList")
    public ActionResult<?> getList() {

        List<String> list = demoService.getList();
        return success(list);
    }

    @GetMapping("/test01")
    public Object test01() {
        System.out.println("person:" + person);
        System.out.println("osname:" + osName);
        return person;
    }

    @ApiIgnore
    @GetMapping("/test02")
    public Object test02() {
        return System.currentTimeMillis() + "-" + osName;

    }


    @GetMapping("getTables")
    public Object getTables(String schema) {
        List<String> tables = demoService.getTables(schema);
        return tables;
    }


    @GetMapping("getSchemas")
    public Object getSchemas() {
        List<HashMap<String, String>> schemaMaps = metaDataMapper.getSchemas();
        List<String> schemas = schemaMaps.stream().map(r -> r.get("SCHEMA_NAME")).collect(Collectors.toList());
        return schemas;
    }

    @GetMapping("getRows")
    public Object getSchemas(String sql) {
        List<HashMap<String, String>> rows = metaDataMapper.getRows(sql);

        return rows;
    }


//    /**
//     * 发送请求
//     *
//     * @return
//     */
//
//    @GetMapping(value = {"Test02", "Test0202"})
//    public Object Test02() {
//        UiIcbcClient client = new UiIcbcClient("", IcbcConstants.SIGN_TYPE_RSA2, "MY_PRIVATE_KEY", IcbcConstants.CHARSET_UTF8);
//        Map<String, String> map = new HashMap<>();
//        map.put("appid", "123456");
//        map.put("bizContent", "{\"merId\":\"020002040095\"}");
//        String res = HttpClientUtil.httpPost("https://gw.open.icbc.com.cn/api/cardbusiness/qrcode/qrgenerate/V1", map);
//        return res;
//    }

    @PostMapping("testPojoParams")
    public String testPojoParams(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        String name = request.getParameter("name");
        return name;
    }

    @GetMapping("testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setContentType("text/html;");
        response.setCharacterEncoding("utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("我是一名小学生student");
        System.out.println("继续执行");
        Thread.sleep(1000);
        System.out.println("休息1s继续执行");
        StringBuffer url1 = request.getRequestURL();
        StringBuffer url2 = request.getRequestURL();
        String domain = url1.delete(url1.length() - request.getRequestURI().length(), url1.length()).append("/").toString();
        String domainContextPath = url2.delete(url2.length() - request.getRequestURI().length(), url2.length()).append(request.getServletContext().getContextPath()).append("/").toString();
        System.out.println(domain);
        System.out.println(domainContextPath);
        System.out.println("ContextPath:" + request.getServletContext().getContextPath());

    }

    @GetMapping("testValid")
    public String testValid(@Validated ValidModel model, BindingResult bindingResult) {
        List<ObjectError> errorList = bindingResult.getAllErrors();
        StringBuilder sb = new StringBuilder();
        for (ObjectError error : errorList) {
            sb.append(",").append(error.getDefaultMessage());
        }
        String errMeg = sb.toString().replaceFirst(",", "-");
        return errMeg;
    }

    @GetMapping("testGet")
    public String testGet(HttpServletRequest request, String name) throws IOException {
        StringBuffer url = request.getRequestURL();
        String domainContextPath = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getServletContext().getContextPath()).append("/").toString();
        String getUrl = domainContextPath + "demo/testGetApi?name=" + name + "&bname=何刘惠";
        String result = HttpClientUtils.get(getUrl);
        return result;
    }

    @GetMapping("testGetApi")
    public String testGetApi(String name, String bname) {
        Map<String, String> map = new HashMap<>();
        map.put("name", name);
        map.put("bname", bname);
        map.put("age", "18");
        map.put("sex", "0");
        return JSON.toJSONString(map);
    }

    @GetMapping("/testGetMapping")
    public String testGetMapping(String name, String bname) {

        return "test";
    }

//    /**
//     * 测试分页 mybatis-plus不能使用该分页，会造成mybatis版本冲突
//     *
//     * @return
//     */
//    @GetMapping("testPaging")
//    public ActionResult testPaging() {
//        //设置分页信息
//        PageHelper.startPage(2,4);
//        List<UserModel> pagingUser = userMapper.getPagingUser();
//        //生成分页数据
//        PageInfo<UserModel> pageInfo=new PageInfo<>(pagingUser);
//        return success(pageInfo);
//    }

    /**
     * TODO 验证码
     *
     * @param request
     * @param response
     */
    public void captcha(HttpServletRequest request, HttpServletResponse response) {

    }

    /**
     * TODO TEST
     *
     * @param args
     */
    public static void main(String[] args) {

        String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
        System.out.println(format);
    }


}
